#include <iostream>
#include <vector>
using namespace std;

struct UFSTree {
    int length;
    int parent;
};

int FIND(vector<UFSTree> &t, int x) {
    if (x != t[x].parent) {
        t[x].parent = FIND(t, t[x].parent);
        return t[x].parent;
    } else {
        return x;
    }
}

void UNION(vector<UFSTree> &t, int x, int y) {
    x = FIND(t, x);
    y = FIND(t, y);
    if (x != y) {
        t[y].parent = x;
    }
}

int main() {

    int M, N, count, first, id;
    cin >> M >> N;
    vector<UFSTree> t(M + 1);
    int maxValue = 0;
    for (int i = 1; i <= M; ++i) {
        t[i].length = 0;
        t[i].parent = i;
    }

    for (int i = 0; i < N; ++i) {
        cin >> count >> first;
        for (int j = 0; j < count - 1; ++j) {
            cin >> id;
            UNION(t, first, id);
        }
    }

    for (int i = 1; i <= M; ++i) {
        id = FIND(t, i);
        t[id].length++;
        maxValue = max(t[id].length, maxValue);
    }

    cout << maxValue << endl;

    return 0;
}